home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / macgambit-20-compiler-src-p1 / Examples / quickdraw-demo.scm < prev    next >
Encoding:
Text File  |  1994-07-26  |  5.1 KB  |  138 lines  |  [TEXT/gamI]

  1. ; Quickdraw demo
  2.  
  3. ; (represent obj) pops up a window with the graphical representation of 'obj'.
  4. ; To get control back, press the mouse button.
  5. ;
  6. ; Note that, contrary to the Pascal and C version of the Quickdraw procedures,
  7. ; the Scheme procedures take an extra argument: the port to apply the
  8. ; operation on.  The port is always the first argument.
  9.  
  10. (define (represent obj)
  11.  
  12.   (define v-offs  0) ; vertical offset of grid
  13.   (define h-offs 20) ; horizontal
  14.  
  15.   (define grid-v 24) ; vertical spacing between grid lines
  16.   (define grid-h 48) ; horizontal
  17.  
  18.   (define cons-v 12) ; vertical size of cons cell
  19.   (define cons-h 24) ; horizontal
  20.  
  21.   (define arrow-head-length 6) ; size of arrows
  22.   (define arrow-head-width  6)
  23.   (define arrow-space       2)
  24.  
  25.   (define fontsize 12)
  26.  
  27.   (let ((w (mac#newwindow
  28.              (mac#rect 40 10 250 500)
  29.              "Box Representation"
  30.              #t    ; visible
  31.              4     ; nogrowdoc
  32.              -1    ; in front of all windows
  33.              #t))) ; goawaybox
  34.  
  35.     (define (draw-cons-cell x y)
  36.       (let ((v (+ (* y grid-v) v-offs))
  37.             (h (+ (* x grid-h) h-offs)))
  38.         (mac#framerect w (mac#rect v h (+ v cons-v) (+ h cons-h)))
  39.         (mac#moveto w (+ h (quotient cons-h 2)) v)
  40.         (mac#line w 0 (- cons-v 1))))
  41.  
  42.     (define (draw-car-arrow x y d) ; draw arrow downwards 'd' grid squares
  43.       (let ((v (+ (* y grid-v) v-offs))
  44.             (h (+ (* x grid-h) h-offs)))
  45.         (mac#moveto w (+ h (quotient cons-h 4)) (+ v (quotient cons-v 2)))
  46.         (mac#line w 0 (- (* d grid-v) (+ (quotient cons-v 2) arrow-space)))
  47.         (mac#line w (quotient arrow-head-width 2) (- arrow-head-length))
  48.         (mac#move w (- arrow-head-width) 0)
  49.         (mac#line w (quotient arrow-head-width 2) arrow-head-length)))
  50.  
  51.     (define (draw-cdr-arrow x y d) ; draw arrow to the right 'd' grid squares
  52.       (let ((v (+ (* y grid-v) v-offs))
  53.             (h (+ (* x grid-h) h-offs)))
  54.         (mac#moveto w (+ h (quotient (* cons-h 3) 4)) (+ v (quotient cons-v 2)))
  55.         (mac#line w (- (* d grid-h) (+ (quotient (* cons-h 3) 4) arrow-space)) 0)
  56.         (mac#line w (- arrow-head-length) (quotient arrow-head-width 2))
  57.         (mac#move w 0 (- arrow-head-width))
  58.         (mac#line w arrow-head-length (quotient arrow-head-width 2))))
  59.  
  60.     (define (draw-nil x y) ; draw nil in cdr of cons cell
  61.       (let ((v (+ (* y grid-v) v-offs))
  62.             (h (+ (* x grid-h) h-offs)))
  63.         (mac#moveto w (+ h (quotient cons-h 2)) (+ v (- cons-v 1)))
  64.         (mac#line w (- (quotient cons-h 2) 1) (- (- cons-v 1)))))
  65.  
  66.     (define (object->string obj)
  67.       (let ((port (open-output-string)))
  68.         (write obj port)
  69.         (let ((str (get-output-string port)))
  70.           (close-output-port port)
  71.           str)))
  72.  
  73.     (define (object-length obj) ; length of object in grid squares
  74.       (cond ((null? obj)
  75.              0)
  76.             ((pair? obj)
  77.              (+ 1 (object-length (cdr obj))))
  78.             (else
  79.              (+ 1 (quotient (+ (mac#stringwidth w (object->string obj)) fontsize)
  80.                             grid-h)))))
  81.  
  82.     (define (initial-profile) 0)
  83.     (define (car-profile p) (if (pair? p) (car p) p))
  84.     (define (cdr-profile p) (if (pair? p) (cdr p) p))
  85.  
  86.     (define (make-profile len p)
  87.       (define (fit1 len p)
  88.         (if (> len 1)
  89.           (let ((p* (fit1 (- len 1) (cdr-profile p))))
  90.             (cons (car-profile p*) p*))
  91.           (fit2 (+ (car-profile p) 1) p)))
  92.       (define (fit2 y p)
  93.         (if (pair? p)
  94.           (cons (max y (car-profile p)) (fit2 y (cdr-profile p)))
  95.           (max y p)))
  96.       (fit1 len p))
  97.  
  98.     (define (draw-list lst x y p)
  99.       (draw-cons-cell x y)
  100.       (let* ((tail (cdr lst))
  101.              (tail-p (cdr-profile p))
  102.              (new-p (cond ((null? tail)
  103.                            (draw-nil x y)
  104.                            tail-p)
  105.                           ((pair? tail)
  106.                            (draw-cdr-arrow x y 1)
  107.                            (draw-list tail (+ x 1) y tail-p))
  108.                           (else
  109.                            (draw-cdr-arrow x y 1)
  110.                            (mac#move w arrow-space (quotient fontsize 2))
  111.                            (mac#drawstring w (object->string tail))
  112.                            tail-p))))
  113.         (draw-object (car lst) x y (cons (car-profile p) new-p))))
  114.  
  115.     (define (draw-object obj x y p)
  116.       (if (pair? obj)
  117.         (let ((len (object-length obj)))
  118.           (let ((new-p (make-profile len p)))
  119.             (let ((yy (car-profile new-p)))
  120.               (draw-car-arrow x y (- yy y))
  121.               (draw-list obj x yy new-p))))
  122.         (let ((text (object->string obj)))
  123.           (draw-car-arrow x y 1)
  124.           (mac#move w (- (quotient (mac#stringwidth w text) 2)) fontsize)
  125.           (mac#drawstring w text)
  126.           (make-profile 1 p))))
  127.  
  128.     (if (not (= w 0)) ; make sure it was created...
  129.       (begin
  130.         (mac#textfont w 3) ; geneva
  131.         (mac#textface w 1) ; bold
  132.         (mac#textsize w fontsize)
  133.         (draw-object obj 0 0 (initial-profile))
  134.         (let loop () (if (not (mac#button)) (loop)))
  135.         (mac#disposewindow w)))))
  136.  
  137. (represent '(define (fact n) (if (< n 2) 1 (* (fact (- n 1)) n))))
  138.